using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Navigation;
using Microsoft.Practices.Composite.Presentation.Commands;

namespace WizardSample
{
    /// <summary>
    /// 
    /// </summary>
    public class NextButtonEnabledConverter : IValueConverter
    {
        public object Convert(object value, Type targetType,
            object parameter, System.Globalization.CultureInfo culture)
        {
            if (value != null && value is Boolean)
            {
                return ((Boolean) value);
            }
            return null;
        }

        public object ConvertBack(object value, Type targetType,
            object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    /// <summary>
    /// 
    /// </summary>
    public class WizardPageBase : UserControl
    {
        public WizardPageBase()
            : base()
        {
        }

        public virtual void BindToData(Object contextData)
        {
            throw new NotImplementedException();
        }

        public Window WizardWindow
        {
            get; set;
        }
    }

    /// <summary>
    /// 
    /// </summary>
    public partial class WizardDialog : Window
    {
        private List<WizardPageBase> wizardPageList;
        private Int32 wizardStep;

        /// <summary>
        /// 
        /// </summary>
        public WizardDialog()
        {
            InitializeComponent();
            // Bind wizard state to UI
            this.WizardData = null;
            this.wizardPageList = new List<WizardPageBase>();
            this.CommandNext = new DelegateCommand<Object>(OnNextCommand);
        }

        public WizardDialog(Object wizardData)
        {
            InitializeComponent();
            // Bind wizard state to UI
            this.WizardData = wizardData;
            this.wizardPageList = new List<WizardPageBase>();
            this.CommandNext = new DelegateCommand<Object>(OnNextCommand);
        }

        /// <summary>
        /// 
        /// </summary>
        public ICommand CommandNext
        {
            get; private set;
        }

        private void OnNextCommand(Object sender)
        {
            nextButton_Click(sender, null);
        }

        public bool IsNextButtonEnabled
        {
            get { return false; }
        }

        /// <summary>
        /// 
        /// </summary>
        public void Start()
        {
            this.wizardStep = 0;
            this.Navigate();
        }

        public void AddPage(WizardPageBase ctrlPage)
        {
            ctrlPage.WizardWindow = this;
            this.wizardPageList.Add(ctrlPage);
        }

        public Object WizardData
        {
            get { return this.DataContext; }
            set { this.DataContext = value; }
        }

        public EventHandler<ReturnEventArgs<WizardResult>> WizardReturn;

        /// <summary>
        /// 
        /// </summary>
        private void SetButtonStates()
        {
            this.finishButton.IsEnabled = true;
            this.backButton.IsEnabled = true;
            this.nextButton.IsEnabled = true;
            this.finishButton.Visibility = this.IsLast
                                               ?
                                                   Visibility.Visible
                                               : Visibility.Collapsed;
            this.backButton.Visibility = this.IsFirst
                                             ?
                                                 Visibility.Collapsed
                                             : Visibility.Visible;
            this.nextButton.Visibility = this.IsLast
                                             ?
                                                 Visibility.Collapsed
                                             : Visibility.Visible;
        }

        private bool IsLast
        {
            get { return (this.wizardStep == this.wizardPageList.Count - 1); }
        }

        private bool IsFirst
        {
            get { return (this.wizardStep == 0); }
        }

        private bool IsIntermediate
        {
            get { return (this.wizardStep > 0 && this.wizardStep < this.wizardPageList.Count - 1); }
        }

        private void Navigate()
        {
            this.panelContent.Children.Clear();
            WizardPageBase wizardPage = this.wizardPageList [this.wizardStep];
            wizardPage.BindToData(this.WizardData);
            this.panelContent.Children.Add(wizardPage);
            this.panelContent.UpdateLayout();
            this.SetButtonStates();
        }

        /// <summary>
        /// 
        /// </summary>
        private void nextButton_Click(object sender, RoutedEventArgs e)
        {
            if (this.wizardStep < this.wizardPageList.Count - 1)
            {
                ++ this.wizardStep;
                this.Navigate();
            }
        }

        void cancelButton_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
            /*
            if (this.WizardReturn != null)
            {
                this.WizardReturn(this, new ReturnEventArgs<WizardResult>(WizardResult.Canceled));
            }
            */
        }

        public void finishButton_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = true;
            /*
            if (this.WizardReturn != null)
            {
                this.WizardReturn(this, new ReturnEventArgs<WizardResult>(WizardResult.Finished));
            }
            */
        }

        private void backButton_Click(object sender, RoutedEventArgs e)
        {
            if (this.wizardStep > 0)
            {
                -- this.wizardStep;
                this.Navigate();
            }
        }
    }
}